<div class="g-form">
    <form class="layui-form" action="" id="project_form" lay-filter="project-form">
        <div class="pro-form-content">
            <div class="pro-form-content-left">
                <div class="layui-form-item">
                    <label class="layui-form-label red-star">项目名</label>
                    <div class="layui-input-block">
                        <input name="name"
                               lay-verify="required"
                               lay-reqText="项目名称不允许为空"
                               lay-verType="tips"
                               autocomplete="off"
                               value="test"
                               placeholder="填写项目名称"
                               class="layui-input">
                    </div>
                </div>

                <div class="layui-form-item">
                    <label class="layui-form-label red-star">包名</label>
                    <div class="layui-input-block">
                        <input name="packageDir"
                               lay-verify="required"
                               lay-reqText="包名不允许为空"
                               lay-verType="tips"
                               placeholder="填写包名"
                               value="com.example"
                               class="layui-input">
                    </div>
                </div>

                <div class="layui-form-item">
                    <label class="layui-form-label">备注信息</label>
                    <div class="layui-input-block">
                        <input name="remark" placeholder="填写项目描述信息" class="layui-input">
                    </div>
                </div>

                <div class="layui-form-item">
                    <label class="layui-form-label red-star">添加模块</label>
                    <div class="layui-input-block">
                        <div class="module-input-container">
                            <input id="moduleInput" placeholder="填写模块名称" class="layui-input">
                            <a id="moduleAddBtn" class="layui-btn">添加</a>
                        </div>
                        <div class="module-content"></div>
                    </div>
                </div>

                <div class="pro-form-content-mid">
                    <!-- 选择实体类 -->
                    <div class="model-select-head">
                        <div class="model-select-head-left">
                            <label for="moduleListSelector">分配给: </label>
                            <select id="moduleListSelector" lay-filter="module-select">
                                <option value="">请选择模块</option>
                            </select>
                        </div>
                        <a class="layui-btn" id="distributeModelBtn">分配</a>
                    </div>
                    <div class="model-select-body">
                        <div id="modelListShow"></div>
                    </div>
                </div>
            </div>
<!--            <div class="pro-form-content-mid">-->
                <!-- 选择实体类 -->
<!--                <div class="model-select-head">-->
<!--                    <label for="moduleListSelector">分配给: </label>-->
<!--                    <select id="moduleListSelector" lay-filter="module-select">-->
<!--                        <option value="">请选择模块</option>-->
<!--                    </select>-->
<!--                </div>-->
<!--                <div class="model-select-body">-->
<!--                    <div class="model-select-body-title">选择实体类</div>-->
<!--                    <div class="model-select-body-main" id="modelListShow"></div>-->
<!--                </div>-->
<!--                <div class="model-select-foot">-->
<!--                    <a class="layui-btn" id="distributeModelBtn">分配</a>-->
<!--                </div>-->
<!--            </div>-->
            <div class="pro-form-content-right">
                <div class="pro-struc-title">项目结构树</div>
                <div class="pro-struc-content">
                    <div id="proStructureTree" class="demo-tree demo-tree-box"></div>
                </div>
            </div>
        </div>
        <div class="pro-form-footer">
            <button type="submit" class="layui-btn" lay-submit lay-filter="pro-form-submit" title="生成源码并下载">生成源码</button>
            <button class="layui-btn layui-btn-primary" id="closeBtn">关闭</button>
        </div>
    </form>
</div>

<script>
    layui.use(['layer', 'tree', 'form', 'admin', 'global', 'transfer'], function () {
        var assit = layui.admin
        var form = layui.form
        var layer = layui.layer
        var $ = layui.$
        var config = layui.global
        var tree = layui.tree
        var transfer = layui.transfer

        const modelList = config.getCache('pro-form-data')
        if (modelList.length < 1) {
            setTimeout(_ => layer.msg('请先选择实体类，再进入', {icon: 3, anim: 6}), 1000)
            assit.finishPopupCenter()
            return false
        }

        form.render('select', 'project-form')

        const PRO_STRUCTURE_ID = 'PRO_STRUCTURE_TREE'
        const MODEL_CHOOSE_ID = 'MODEL_CHOOSE_TRANSFER'
        const MAX_MODULE_CNT = 8
        const MODULE_ITEM_PREFIX = 'M_ID_'
        const moduleIds = []
        const proTreeData = [
            {
                id: '_0',
                spread: true,
                title: 'test',
                children: [
                    {
                        id: '_1',
                        title: 'com.example',
                        spread: true,
                        children: []
                    }
                ]
            }
        ]

        // const BAN_MODULE = ['controller', 'rest', 'entity', 'model', 'mapper', 'service', 'impl']

        tree.render({
            elem: '#proStructureTree',
            data: proTreeData,
            id: PRO_STRUCTURE_ID,
        })

        transfer.render({
            elem: '#modelListShow',
            id: MODEL_CHOOSE_ID,
            data: modelList,
            height: 190,
            title: ['待选实体类', '已选实体类'],
            onchange: function (data, index) {
                //console.log(index, data); //如果数据来自左边，index 为 0，否则为 1
                // console.log(data); //得到当前被穿梭的数据
                const curModule = getSelectedModule()
                if (index === 0) {
                    // 选择
                } else if (index === 1) {
                    console.log('选中的model:',curModule,'\ndata:', data)
                    // 取消选择
                    let idx = proTreeData[0].children[0].children.findIndex(o => o.id === curModule)
                    const fa = proTreeData[0].children[0].children[idx]
                    if (idx > -1 && fa.children && fa.children.length > 0) {
                        // 有效模块
                        // 移除结构树上的节点
                        // 增加 modelList
                        let isUpdate = false
                        $.each(data, (i, o) => {
                            let iii = fa.children.findIndex(oo => oo.id === o.value)
                            if (iii > -1) {
                                isUpdate = true
                                fa.children.splice(iii, 1)
                                modelList.push({id: o.value, name: o.title})
                            }
                        })
                        if (isUpdate)
                            tree.reload(PRO_STRUCTURE_ID, {data: proTreeData})
                    }

                }
            },
            parseData: function (r) {
                return {
                    "value": r.id,
                    "title": r.name,
                    "disabled": r.disabled,
                    "checked": r.checked,
                }
            }
        })

        // $.each(modelList, (index, item) => {
        //     // <input type="checkbox" name="col[5]" value="5" title="deleteFlag" lay-skin="primary">
        //     $('#modelListShow').append(
        //         '<input class="model-id" type="checkbox" value="'+ item.id
        //         + '" title="' + item.name + '" lay-skin="primary">')
        // })
        // form.render('checkbox', 'project-form')

        $('input[name=name]').on('input', function (e) {
            proTreeData[0].title = this.value.trim()
            tree.reload(PRO_STRUCTURE_ID, {data: proTreeData})
        })

        $('input[name=packageDir]').on('input', function (e) {
            proTreeData[0].children[0].title = this.value.trim()
            tree.reload(PRO_STRUCTURE_ID, {data: proTreeData})
        })

        $('#moduleInput').on('keypress', function (event) {
            if (event.keyCode === 13) {
                handleModuleAdd()
                return false
            }
        })

        $('#moduleAddBtn').on('click', function () {
            handleModuleAdd()
            return false
        })

        $('.module-content').on('click', '.module-del-icon', function (o) {
            // var txt = o.currentTarget.innerText
            const id = o.currentTarget.id.substring(MODULE_ITEM_PREFIX.length)
            let arr = proTreeData[0].children[0].children;
            $(this).parent().remove()
            arr = arr.filter(o => o.id !== id);
            proTreeData[0].children[0].children = arr
            tree.reload(PRO_STRUCTURE_ID, {data: proTreeData})
            moduleIds.splice($.inArray(id, moduleIds), 1)
            renewModuleSelector()
        })

        form.on('select(module-select)', function(d) {
            // 搜索结构树上是否有当前模块的实体类
            if (d.value !== 'undefined' && d.value !== '') {
                let i = proTreeData[0].children[0].children.findIndex((o) => o.id === d.value)
                if (i > -1) {
                    // 存在，接着获取它的实体类
                    let fa = proTreeData[0].children[0].children[i]
                    if (fa.children && fa.children.length > 0) {
                        // 已经选择了某些实体类
                        const selected = []
                        // 重新复制一份
                        const nArr = JSON.parse(JSON.stringify(modelList))
                        $.each(fa.children, (i, o) => {
                            selected.push(o.id)
                            // 合并到 modelList
                            nArr.push({id: o.id, name: o.title})
                        })
                        // 重新渲染 transfer
                        transfer.reload(MODEL_CHOOSE_ID, {value: selected, data: nArr})
                        return
                    }
                }
            }
            transfer.reload(MODEL_CHOOSE_ID, {data: modelList, value:[]})
        })

        $('#distributeModelBtn').on('click', function (e) {
            // 获取选中的 model
            const models = transfer.getData(MODEL_CHOOSE_ID)
            console.log('已选择:', models)
            var that = this
            if (models.length < 1) {
                layer.tips('请先选择实体类', that, {tips: 1})
                return false
            }
            // 获取选中的 module
            var moduleName = getSelectedModule()
            if (moduleName === '') {
                layer.tips('请选择要分配的模块', that, {tips: 1})
                return false
            }

            // 渲染到结构树上
            var idx = proTreeData[0].children[0].children.findIndex((o) => o.id === moduleName)
            if (idx > -1) {
                var fa = proTreeData[0].children[0].children[idx]
                fa.children = []
                $.each(models, (i, o) => {
                    fa.children.push({id: o.value, title: o.title})
                    let index = modelList.findIndex(oo => oo.id === o.value)
                    // 从 modelList 去除
                    modelList.splice(index, 1)
                })

                console.log('剩余的model:', modelList)

                tree.reload(PRO_STRUCTURE_ID, {data: proTreeData})
            }
        })

        form.on('submit(pro-form-submit)', function (data) {
            if (moduleIds.length < 1) {
                // 没有输入模块
                layer.msg('至少要添加一个模块', {anim: 6})
                return false
            }

            const oo = proTreeData[0].children[0].children
            // 遍历每个模块下是否有实体类
            let modules = []
            for (let i = 0; i < oo.length; ++i) {
                // 只记录有实体类的模块
                if (oo[i].children && oo[i].children.length > 0) {
                    let ot = {}
                    ot.modelIds = oo[i].children.map(o => o.id)
                    ot.name = oo[i].id
                    modules.push(ot)
                }
            }

            if (modules.length < 1) {
                layer.msg('请至少为一个模块添加实体类', {anim: 6})
                return false
            }

            const obj = {
                projectName: data.field.name,
                packageName: data.field.packageDir,
                projectDesc: data.field.remark,
                moduleList: modules
            }
            layer.load(0, {shade: 0.6})
            assit.post('/project/code/download', obj, {
                responseType: 'blob',
                onDownloadProgress: function (pe) {
                    console.log(Math.round(pe.loaded / pe.total * 100) + '%')
                }
            }).then(r => {
                console.log('==>', r)
                const blob = new Blob([r.data])
                let url = URL.createObjectURL(blob)
                const a = document.createElement("a")
                a.download = obj.projectName + ".zip"
                a.style.display = "none"
                a.href = url
                document.body.appendChild(a)
                a.click()
                // 释放这个临时的对象 url
                URL.revokeObjectURL(url)
                document.body.removeChild(a)
                setTimeout(_ => layer.closeAll('loading', () => assit.finishPopupCenter()), 800)
            }).catch(e => {
                layer.closeAll('loading')
            })
            return false
        })

        $('#closeBtn').on('click', function (e) {
            assit.closePopupCenter()
            return false // 禁止页面刷新、跳转
        })

        function getSelectedModule() {
            let moduleName = $('#moduleListSelector option:selected').val()
            if (typeof moduleName === 'string' && moduleName !== '') {
                return moduleName
            }
            return ''
        }

        function handleModuleAdd () {
            const v = $('#moduleInput').val().trim()
            if (v !== '') {
                if (MAX_MODULE_CNT <= moduleIds.length) {
                    layer.tips('最多只能创建' + MAX_MODULE_CNT + '个模块',
                        '#moduleInput', {tips: 1})
                    return false
                }
                if (moduleIds.some(e => e === v)) {
                    layer.tips('该模块名已存在', '#moduleInput', {tips: 1})
                    return false
                } else {
                    proTreeData[0].children[0].children.push({title: v, id: v, spread: true})
                    tree.reload(PRO_STRUCTURE_ID, {data: proTreeData})
                    moduleIds.push(v)
                    $('#moduleInput').val('')
                    const id = MODULE_ITEM_PREFIX + v
                    $(".module-content").append(
                        '<span class="layui-badge-rim layui-bg-black module-name-content">'
                        + '<span class="module-name-title">' + v + '</span>'
                        + '<i title="删除本模块" id="' + id + '" class="layui-icon layui-icon-close-fill module-del-icon"></i>'
                        + '</span>'
                    )
                    renewModuleSelector()
                }
            }
        }

        function renewModuleSelector() {
            var el = $('#moduleListSelector')
            el.find('option').remove()
            el.append('<option value="">请选择模块</option>')
            $.each(moduleIds, (index, item) => {
                el.append("<option value='" + item + "'>" + item + "</option>")
            })
            form.render('select', 'project-form')
        }

        // function clearModelChoose() {
        //     var chks = $('#modelListShow .model-id');
        //     $.each(chks, (i, o) => {
        //         $(o).prop('checked', false)
        //     })
        //     form.render('checkbox', 'project-form')
        // }

        // function getSelectedModel() {
        //     var items = $('#modelListShow .model-id')
        //     var ids = []
        //     $.each(items, (i, o) => {
        //         const checked = $(o).prop('checked')
        //         if (checked) {
        //             var v = $(o).val()
        //             ids.push(v)
        //         }
        //     })
        //     return modelList.filter(o => ids.some(oo => oo === o.id))
        // }

    })
</script>